package io.xxx.mario.robot;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.xxx.mario.config.RateLimiterManager;
import io.xxx.mario.exception.NoTokenException;
import io.xxx.mario.robot.api.ApplyRobotRequest;
import io.xxx.mario.robot.api.SaveRobotRequest;
import io.xxx.mario.wechaty.RobotClient;
import io.xxx.mario.wechaty.request.GetLoginQrcodeRobotRequest;
import io.xxx.mario.wechaty.response.GetLoginQrcodeRobotResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

@Slf4j
@Service
public class RobotService {

    @Resource
    private ConversionService conversionService;

    @Resource
    private RobotMapper robotMapper;

    @Resource
    private WechatyPuppetMapper wechatyPuppetMapper;

    @Resource
    private WechatyPuppetService wechatyPuppetService;

    @Resource
    private RateLimiterManager rateLimiterManager;

    @Resource
    private RobotClient robotClient;

    @Resource
    private Map<String, RobotAssignor> assignors;

    public String getLoginQrcode() {
        WechatyPuppet wechatyPuppet = wechatyPuppetMapper.findByUsed(false);
        if (wechatyPuppet == null) {
            throw new NoTokenException();
        }

        GetLoginQrcodeRobotRequest request = new GetLoginQrcodeRobotRequest();
        request.setId(IdWorker.getId());
        request.setToken(wechatyPuppet.getToken());
        GetLoginQrcodeRobotResponse response = robotClient.execute(request);
        return response.getQrcodeImageUrl();
    }

    /**
     * 机器人登录后需要保存身份信息
     */
    @Transactional
    public void save(SaveRobotRequest request) {
        Robot robot = conversionService.convert(request, Robot.class);
        if (robot == null) {
            return;
        }
        rateLimiterManager.add(robot.getId());
        robotMapper.insert(robot);
        wechatyPuppetService.useToken(robot.getPuppetId());
    }

    /**
     * 删除一个机器人
     */
    public void remove() {

    }

    /**
     * 申请机器人
     */
    public Robot applyRobot(ApplyRobotRequest request) {
        request.validate();
        for (RobotAssignor assignor : assignors.values()) {
            Robot robot = assignor.assign(request);
            if (robot != null) {
                return robot;
            }
        }
        return null;
    }
}
